﻿using System;
using System.Reflection;
using System.Windows;
using System.Linq;
using System.ComponentModel.Composition;
using System.Collections.Generic;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using GlobalOfficeTools.Interfaces.ViewModel;
using GlobalOfficeTools.Framework.MvvmLocator;
using GlobalOfficeTools.Framework.ChildWindowService;
using GlobalOfficeTools.Interfaces.Model;
using GlobalOfficeTools.MVC3.Models;
using GlobalOfficeTools.MessagesDto;

using SilverlightMenu.Library;

namespace GlobalOfficeTools.ViewModels
{
    [ExportViewModel("MainPageViewModel")]
    public class MainPageViewModel : ViewModelBase, IMainPageViewModel
    {
        #region Private Fields 
        private IChildWindowService _childWindowService;
        private IClientsModel _clientsModel;
        private ISystemModel _systemModel;

        private bool _isBusy;
        private string _userName;
        private string _password;
        private MenuItem _menuItems;

        private string _softwareVersion;
        private string _logonUserName;
        private string _activeCompany;

        private Visibility _loginBoxVisibility;
        private Visibility _userDetailsBoxVisibility;
        
        #endregion

        #region Constructor 
        [ImportingConstructor]
        public MainPageViewModel([Import(typeof(IClientsModel))] IClientsModel clientsModel, [Import(typeof(ISystemModel))] ISystemModel systemModel, [Import(typeof(IChildWindowService))] IChildWindowService childWindowService)
        {
            _childWindowService = childWindowService;
            _clientsModel = clientsModel;
            _systemModel = systemModel;

            this.ImagesPath = "../Images/";
            this.LoginBoxVisibility = Visibility.Visible;
            this.UserDetailsBoxVisibility = Visibility.Collapsed;

            LoginButton = new RelayCommand(() => LoginButtonCommand());
            MenuCommand = new RelayCommand<object>(x => { ProcessMenuClick(x as MenuItem); });
        }
        #endregion

        #region IMainPageViewModel Implementation 
        public bool IsBusy 
        {
            get { return _isBusy; }
            set 
            {
                _isBusy = value;
                RaisePropertyChanged(() => IsBusy);
            }
        }
        public string UserName 
        {
            get { return _userName; }
            set 
            { 
                _userName = value; 
                RaisePropertyChanged(() => UserName);
            }
        }
        public string Password 
        {
            get { return _password; }
            set 
            {
                _password = value;
                RaisePropertyChanged(() => Password);
            }
        }
        public MenuItem MenuItems 
        {
            get { return _menuItems; }
            set 
            {
                _menuItems = value;
                RaisePropertyChanged(() => MenuItems);
            }
        }
        public string ImagesPath { get; set; }                      // this is doing nothing here because it's not using images in the menu

        public string SoftwareVersion 
        {
            get { return _softwareVersion; }
            set 
            {
                _softwareVersion = value;
                RaisePropertyChanged(() => SoftwareVersion);
            }
        }
        public string LogonUserName 
        {
            get { return _logonUserName; }
            set 
            {
                _logonUserName = value;
                RaisePropertyChanged(() => LogonUserName);
            }
        }
        public string ActiveCompany 
        {
            get { return _activeCompany; }
            set 
            {
                _activeCompany = value;
                RaisePropertyChanged(() => ActiveCompany);
            }
        }

        public Visibility LoginBoxVisibility 
        {
            get { return _loginBoxVisibility; }
            set 
            {
                _loginBoxVisibility = value;
                RaisePropertyChanged(() => LoginBoxVisibility);
            }
        }
        public Visibility UserDetailsBoxVisibility 
        {
            get { return _userDetailsBoxVisibility; }
            set 
            {
                _userDetailsBoxVisibility = value;
                RaisePropertyChanged(() => UserDetailsBoxVisibility);
            }
        }
        
        public RelayCommand<object> MenuCommand { get; private set; }
        public RelayCommand LoginButton { get; private set; }
        #endregion

        #region Private Methods 
        private string GetXAPVersion() 
        {
            var assemblyName = new AssemblyName(Application.Current.GetType().Assembly.FullName);
            if (assemblyName == null) return string.Empty;
            Version v = assemblyName.Version;
            if (v == null) return string.Empty;

            return v.ToString(); 
        }
        private void ProcessMenuClick(MenuItem menuItem) 
        {
            _systemModel.GetMenu(menuItem.Name, result =>
            {
                switch (result.Action)
                {
                    case "VIEW":
                        Messenger.Default.Send<NavigationMessage>(new NavigationMessage() { PageName=result.ActionObject, Parameters=result.ActionParameters });
                        break;
                    case "CHILDWINDOW":
                        _childWindowService.ShowDialog(result.ActionObject);
                        break;
                    default:
                        MessageBox.Show(string.Format("The menu {0} don't have any action configured", menuItem.Name));
                        break;
                }
            });
        }
        private void GenerateMenu(IEnumerable<SYStblMenu> menuList) 
        {
            // this method only support two level menu. I don't think that will be necessary more

            MenuItems = new MenuItem() { Name = "Root" };

            var rootItems = from x in menuList
                            where x.ParentMenuId == -1
                            orderby x.MenuOrder
                            select x;

            foreach (SYStblMenu itemRoot in rootItems)
            {
                var mnuItemRoot = new MenuItem() { Name = itemRoot.Name, Text = itemRoot.Text };
                var childItems = from x in menuList
                                 where x.ParentMenuId == itemRoot.MenuId
                                 orderby x.MenuOrder
                                 select x;
                foreach (SYStblMenu itemChild in childItems)
                {
                    mnuItemRoot.Add(new MenuItem() { Name = itemChild.Name, Text = itemChild.Text });
                }
                MenuItems.Add(mnuItemRoot);
            }
        }
        private void LoginButtonCommand() 
        {
            this.IsBusy = true;
            if (this.UserName.Length <= 0 && this.Password.Length <= 0)
            {
                // TODO: Error message saying that UserName or Password is empty
                this.IsBusy = false;
            }
            else
            {
                _clientsModel.AutheticateUser(this.UserName, this.Password, (resultUser, resultCompany, resultEmployeeType) =>
                {
                    if (resultUser == null)
                    {
                        // TODO: Error message saying that the combination UserName / Password is invalid
                    }
                    else
                    {
                        Globals.LogonUser = resultUser;
                        Globals.ActiveCompany = resultCompany;
                        Globals.ActiveCompanyEmployeeType = resultEmployeeType;

                        // Load the menu for the user
                        _systemModel.ListMenus(resultMenuItems => 
                        {
                            _clientsModel.GetAccessList(Globals.LogonUser.UserId, Globals.ActiveCompany.CompanyId, aclResult =>
                            {
                                List<SYStblMenu> lstRET = new List<SYStblMenu>();       // List of menu after check if user has access
                                foreach (SYStblMenu item in resultMenuItems)
                                {
                                    var aclItem = (from x in aclResult
                                                   where x.Resource == "MENU" && x.ResourceId == item.MenuId
                                                   select x).FirstOrDefault();

                                    if (aclItem != null) lstRET.Add(item);
                                }

                                GenerateMenu(lstRET);
                                Messenger.Default.Send<MenuItem>(MenuItems); 
                            });
                        });
                        this.LoginBoxVisibility = Visibility.Collapsed;
                        this.UserDetailsBoxVisibility = Visibility.Visible;

                        this.SoftwareVersion = string.Format("{0}", GetXAPVersion());
                        this.LogonUserName = string.Format("{0} ({1})", Globals.LogonUser.FullName, Globals.ActiveCompanyEmployeeType.EmployeeType);
                        this.ActiveCompany = Globals.ActiveCompany.FullName;
                    }

                    this.IsBusy = false;
                });
            }
        }
        #endregion
    }
}
